import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.codec.binary.Base64;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @Des Created by wh_king on 2019/10/16.
 */
public class RSA {
    public static String SIGN_ALGORITHMS = "SHA256withRSA";
    private static String CHAR_SET = "UTF-8";
    private static String CIPHER_MODE = "RSA";

    public static  String PRIVATE_KEY =
            new StringBuffer("MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDQqkZxazwTnOms")
                    .append("T1NdjDnb6srF22GHAVkRHM8Agh6EpYvUZwMM1NEWbFEkO+Nwi/6+G5pB9hlhD6ML")
                    .append("1vnZvcTilV2F+iM3EkB3Q8lY6MgRleOESk+V+IOnROuNwqw7hWLBi7wDZTJX9v/1")
                    .append("5mKKkXHQuZZs3tkBmMkPrnmnmQk8A+NTalPrLL+yUGpolYgzmpsqraofhg6rjtwQ")
                    .append("dhnRr9xMne8bOUtVqjk5VWEeDtPakhjCpygjUB7HH3cvrOsMUYLRsJqAOAPLOR4K")
                    .append("Csxj7Y8SrwhKII6YsRv2EfTlzy83FSCPyiXMGn/snQ8hONA6P/YadHrnrEIsTfqZ")
                    .append("+lkC/ZpvAgMBAAECggEBAMu65GpKi+6OTqwZC0kT503r0S0bA/7fdwm5OfbCFG/o")
                    .append("fjzUkurNQpQFD7gz7N1vIjqVEqiCUscskEG4FFve58NemGB+GDHl1SFdAtKW/PgG")
                    .append("g4wfTdMcP9Zp+R6Ays6WbhSQjPI3tM6j78czuFSYqypieRc1AWWIug5giJD1X0nC")
                    .append("sX9ZZolr4tTk2RqykbiAVVmX1L2aezE/FLoyuqdZ8kWQXlJZS3ldOvECTy0fuV0v")
                    .append("sJ/Mmm27efkONTlcBNzLr8blhuKmQbTC0IBeUoOiP7lXcK+2gYbf9JVEj56MBVYs")
                    .append("0vyPNRB9gy/HPQlov05ZieIH87za3oTz5Vb+HTb9+CECgYEA+MGDiX04O7kAD5s5")
                    .append("UXY5OeTgviilPdBm7JpsiezHDKN7S3oy/4P5GJ/eei8uVkCdrN01h35pMiDq/jkm")
                    .append("0UihXJjaZ2+MHAhMM7l2AONT7MzAisRnnFUeyVYaCRhUJfwrl+ERBP2vHCkNa34O")
                    .append("JmdL8XQf7Met+KcYSKLF8qLYFL8CgYEA1r3iA6RP/0F8XyQRL1aF9cJVQpWPwI/V")
                    .append("6jLq+v/mhzlTdy5c4u9nMvhh+yjUPwZomQshby9MbRv0x0jdE9Hnn03lUcVJocZv")
                    .append("owUBr34qIkC3x3LhwPC+rIa3/x9FSiN2fGP2lADAXDmnxt+6UlqX5wuhq/jIbT+R")
                    .append("55zsrjWxdlECgYAvAlr6Q5i56JczW9E0LNRZtYAnT4USrmyU8AXs9rsTD14AgIJc")
                    .append("uTL8zVF846etEx75CQDRrzjwCTp/eot0Z3ZfCl/TxkfDEGpeKAE937f/ex4z2zP9 ")
                    .append("XjSoNcZLy7YzS3lthVHzEIHkH3nyw2qnJUQ7yAc0dvPQlrtHFsOzu8R7/wKBgD13")
                    .append("dqVCOB/BV99HzJ93LbsN2CfJ9a7RvRJfZsFX1F2qfAimPbI7gpelXy5sHmy34eLE")
                    .append("u9o+eKrWkLcmVRmiQKFpw5UnWo8y5KuN+FCKVXcefTxa1uHKR1nM6gfdpJC3G+g5")
                    .append("GNB+cpEzc6HKUmPWSJq6ypkWChCzXIkmctzew6AxAoGBANq35XF3HxB7f/xmekO7")
                    .append("kJBxT6TUZCMlOZlM5xvFkF4Uqsz1RGq8N1WTUzCDtlEHQknqwuB7HMC2LF0OHgjo")
                    .append("s+Zs05IhooXCXsVlkyxEgf+H8Po8WU//7bjnsJ3rxrHJxVFKVQrcX72nsMbYGkvy")
                    .append("HxtoEnwMwF1bjqjgOqB3m+uR").toString();


    public static String sign(String content, String privateKey) throws Exception {

        try {

            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
            KeyFactory keyf = KeyFactory.getInstance(CIPHER_MODE);
            PrivateKey priKey = keyf.generatePrivate(priPKCS8);

            java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

            signature.initSign(priKey);
            signature.update(content.getBytes(CHAR_SET));

            byte[] signed = signature.sign();

            return Base64.encodeBase64String(signed);

        } catch (Exception ex) {
            throw new Exception(ex.toString());
        }
    }

    /**
     * 1.第json的key 字典排序
     * 2.按排完序的key  获取对应的 value 拼接成字符串
     *
     * @param json
     * @return
     */
    public static String getSignContent(JSONObject json) {
        List<String> keys = new ArrayList<>(json.size());
        for (Map.Entry<String, Object> entry : json.entrySet()) {
            String s = entry.getKey();
            if (!s.equals("sign")) {
                keys.add(s);
            }
        }

        Collections.sort(keys);

        StringBuilder sb = new StringBuilder();

        for (String key : keys) {
            Object v = json.get(key);
            if (v instanceof JSONObject || v instanceof JSONArray) {
                sb.append(JSON.toJSONString(v, SerializerFeature.MapSortField));
            } else {
                sb.append(v == null ? "" : v.toString());
            }
        }

        return sb.toString();
    }

}
